home *** CD-ROM | disk | FTP | other *** search
- /*
- File: MemMgr.cpp
-
- Contains: Procedural API for memory heaps
-
- Owned by: Jens Alfke
-
- Copyright: © 1994-95 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <8> 10/24/95 jpa 1293441: Added slush-fund.
- <7> 8/4/95 DM Leak detection [1267956]
- <6> 6/7/95 jpa Added MMConfiguration [1246897]
- <5> 5/4/95 jpa Added MMGetFreeSpace [1235657] and MMMove
- [1246077]
- <4> 12/5/94 jpa Nuked errant pragma lib_export's. [1195676]
- <3> 10/24/94 jpa Constness [1194286]. MMSplice [1194287].
- <2> 9/29/94 RA 1189812: Mods for 68K build.
- <1> 9/14/94 jpa first checked in
-
- To Do:
- In Progress:
-
- */
-
-
- #ifndef _MEMMGR_
- #include "MemMgr.h"
- #endif
-
- #ifndef _MEMMGRPV_
- #include "MemMgrPv.h"
- #endif
-
- #ifndef _MEMDEBG_
- #include "MemDebg.h"
- #endif
-
-
- #undef SURVEY_SIZES
-
-
- //==============================================================================
- // GLOBAL VARIABLES
- //==============================================================================
-
-
- BestFitHeap *gDefaultHeap;
-
-
- #ifdef SURVEY_SIZES
- const int kNSizeBins = 100;
- unsigned long gSizeBin[kNSizeBins];
- unsigned long gNAllocations;
- #endif
-
-
- //========================================================================================
- // HEAP MANAGEMENT
- //========================================================================================
-
-
- long
- MMConfiguration( )
- {
- return MM_DEBUG ?kMMDebugConfigMask :0;
- }
-
-
- //------------------------------------------------------------------------------
- // MMNewHeap
- //------------------------------------------------------------------------------
-
- MemHeap* MMNewHeap( MMHeapLocation loc, size_t initialSize, size_t growAmount,
- const char *name )
- {
- BestFitHeap *heap = new( (MMHeapLocation)loc )
- BestFitHeap(initialSize,growAmount,0, (MMHeapLocation)loc);
- if( heap ) {
- heap->IBestFitHeap();
- if( name )
- heap->SetDescription(name);
- #if MM_DEBUG
- if( gValidate>0 ) {
- heap->SetZapOnAllocate(kMMTrue);
- heap->SetZapOnFree(kMMTrue);
- heap->SetAutoValidation(kMMTrue);
- }
- #endif
- }
- return (MemHeap*) heap;
- }
-
-
- //------------------------------------------------------------------------------
- // MMDisposeHeap
- //------------------------------------------------------------------------------
-
- void
- MMDisposeHeap( MemHeap *heap )
- {
- delete (BestFitHeap*) heap;
- }
-
-
- //------------------------------------------------------------------------------
- // MMGetDefaultHeap
- //------------------------------------------------------------------------------
-
- MemHeap*
- MMGetDefaultHeap( )
- {
- return (MemHeap*) gDefaultHeap;
- }
-
-
- //------------------------------------------------------------------------------
- // MMSetDefaultHeap
- //------------------------------------------------------------------------------
-
- MemHeap*
- MMSetDefaultHeap( MemHeap *heap )
- {
- MM_ASSERT(heap!=kMMNULL);
- MemHeap *oldDefault = (MemHeap*)gDefaultHeap;
- gDefaultHeap = (BestFitHeap*)heap;
- return oldDefault;
- }
-
-
- //========================================================================================
- // FREE SPACE MANAGEMENT
- //========================================================================================
-
-
- //----------------------------------------------------------------------------------------
- // MMGetFreeSpace
- //----------------------------------------------------------------------------------------
-
- void
- MMGetFreeSpace( MemHeap *heapID, size_t *total, size_t *contig )
- {
- BestFitHeap *heap = (BestFitHeap*)( heapID ?heapID :MMGetDefaultHeap() );
-
- size_t sysTotal, sysContig, heapTotal, heapContig;
-
- MMSystemFreeSpace(heap->GetLocation(),&sysTotal,&sysContig);
- heapTotal = heap->BytesFree();
- size_t incr = heap->GetSizeIncrement();
-
- if( sysContig < incr || sysTotal < incr+kPlatformMinFreeSpace ) {
- // Not enough memory to grow heap, so we're limited to space in heap.
- heapTotal = sysTotal;
- heapContig = heap->LargestFreeBlock();
- } else {
- heapTotal += sysTotal;
- heapContig = sysContig;
- }
-
- if( total ) *total = heapTotal;
- if( contig) *contig= heapContig;
- }
-
-
- MMBoolean
- MMAllocateSlushFund( MemHeap *heapID, size_t size, size_t allocSizeLimit )
- {
- MemoryHeap *heap = heapID ?(MemoryHeap*)heapID :gDefaultHeap;
- return heap->AllocateSlushFund(size,allocSizeLimit);
- }
-
-
- size_t
- MMSlushFundSize( MemHeap *heapID )
- {
- MemoryHeap *heap = heapID ?(MemoryHeap*)heapID :gDefaultHeap;
- return heap->GetSlushFundSize();
- }
-
-
- size_t
- MMFreeSlushFund( MemHeap *heapID )
- {
- MemoryHeap *heap = heapID ?(MemoryHeap*)heapID :gDefaultHeap;
- return heap->FreeSlushFund();
- }
-
-
-
- //========================================================================================
- // OPERATIONS ON BLOCKS
- //========================================================================================
-
-
- #ifdef SURVEY_SIZES
- static void SurveySize( size_t size )
- {
- size_t index = (size+3)>>2;
- if( index >= kNSizeBins )
- index = kNSizeBins-1;
- gSizeBin[index]++;
- gNAllocations++;
- }
- #endif
-
-
- //------------------------------------------------------------------------------
- // MMAllocate
- //------------------------------------------------------------------------------
-
- void*
- MMAllocate( size_t size )
- {
- #if MM_DEBUG
- if( (MMULong)size>BestFitBlock_kMaxBlockSize ) {
- MM_WARN("Bogus size 0x%08lx for MMAllocate",size);
- return kMMNULL;
- }
-
- if( gHeapChecking>0 )
- MMValidateHeap((MemHeap*)gDefaultHeap);
- #endif
-
- #ifdef SURVEY_SIZES
- SurveySize(size);
- #endif
-
- return gDefaultHeap->Allocate(size);
- }
-
-
- //------------------------------------------------------------------------------
- // MMAllocateIn
- //------------------------------------------------------------------------------
-
- void*
- MMAllocateIn( size_t size, MemHeap *heap )
- {
- #if MM_DEBUG
- if( (MMULong)size>BestFitBlock_kMaxBlockSize ) {
- MM_WARN("Bogus size 0x%08lx for MMAllocate",size);
- return kMMNULL;
- }
-
- if( gHeapChecking>0 )
- MMValidateHeap(heap);
- #endif
-
- #ifdef SURVEY_SIZES
- SurveySize(size);
- #endif
-
- return ((BestFitHeap*)heap)->Allocate(size);
- }
-
-
- //------------------------------------------------------------------------------
- // MMAllocateClear
- //------------------------------------------------------------------------------
-
- void*
- MMAllocateClear( size_t size )
- {
- return MMAllocateClearIn(size,(MemHeap*)gDefaultHeap);
- }
-
-
- //------------------------------------------------------------------------------
- // MMAllocateClearIn
- //------------------------------------------------------------------------------
-
- void*
- MMAllocateClearIn( size_t size, MemHeap *heap )
- {
- void *block = MMAllocateIn(size,heap);
- if( block )
- PlatformZapMem(block,size,0);
- return block;
- }
-
-
- //------------------------------------------------------------------------------
- // MMReallocate
- //------------------------------------------------------------------------------
-
- void*
- MMReallocate( void *block, size_t size )
- {
- #ifdef SURVEY_SIZES
- SurveySize(size);
- #endif
-
- if( block==kMMNULL )
- return gDefaultHeap->Allocate(size);
- else {
- BestFitHeap *heap = (BestFitHeap*)MMGetHeap(block);
- if( heap )
- return heap->Reallocate(block,size);
- else
- return kMMNULL;
- }
- }
-
-
- //------------------------------------------------------------------------------
- // MMSplice
- //------------------------------------------------------------------------------
-
- void*
- MMSplice( void *block, size_t offset, long delta )
- {
- // If delta>0, insert bytes at offset. If delta<0, delete bytes at offset.
-
- if( delta==0 ) return block;
- size_t oldSize = block ?MMBlockSize(block) :0;
- MM_ASSERT(offset<=oldSize);
- if( MM_DEBUG && delta<0 )
- MM_ASSERT(offset-delta<=oldSize);
-
- size_t newSize = oldSize + delta;
- void *newBlock;
- if( newSize==0 )
- newBlock = kMMNULL;
- else {
- BestFitHeap *heap = (BestFitHeap*)MMGetHeap(block);
- if( heap )
- newBlock = heap->Allocate(newSize);
- else {
- MM_WARN("Couldn't get block's heap in MMSplice");
- return kMMNULL;
- }
- if( newBlock ) {
- PlatformCopyMemory(block,newBlock,offset);
- if( delta>0 )
- PlatformCopyMemory((char*)block+offset,(char*)newBlock+offset+delta, oldSize-offset);
- else
- PlatformCopyMemory((char*)block+offset-delta,(char*)newBlock+offset, oldSize-offset+delta);
- }
- }
- MMFree(block);
- return newBlock;
- }
-
-
- //------------------------------------------------------------------------------
- // GetHeap [static]
- //------------------------------------------------------------------------------
-
-
- BestFitHeap*
- GetHeap( const void* block, const char *op )
- {
- if (block == kMMNULL)
- {
- MM_WARN("%s(NULL) is bogus, dude",op);
- return kMMNULL;
- }
-
- #if MM_DEBUG
- if( gValidate>0 )
- if( !MMValidatePtr(block,gHeapChecking>0,op) )
- return kMMNULL;
- #endif
-
- return (BestFitHeap*) gDefaultHeap->GetBlockHeap(block); // Should be static but isn't
- }
-
-
-
- //------------------------------------------------------------------------------
- // MMFree
- //------------------------------------------------------------------------------
-
- void
- MMFree( void *block )
- {
- if( block ) {
- BestFitHeap *heap = GetHeap(block,"MMFree");
- if( heap ) {
- #if MM_DEBUG
- // The isObject flag should have been cleared by ODObject::SOMUninit!
- if( heap->BlockIsObject(block) )
- MM_WARN("Object %p unexpectedly disposed!",block);
- #endif
-
- heap->Free(block);
- }
- }
- }
-
-
- //------------------------------------------------------------------------------
- // MMBlockSize
- //------------------------------------------------------------------------------
-
- size_t
- MMBlockSize( const void *block )
- {
- BestFitHeap *heap = GetHeap(block,"MMBlockSize");
- if( heap )
- return heap->BlockSize(block);
- else
- return 0;
- }
-
-
- //------------------------------------------------------------------------------
- // MMGetHeap
- //------------------------------------------------------------------------------
-
- MemHeap*
- MMGetHeap( const void* block )
- {
- return (MemHeap*) GetHeap(block,"MMGetHeap");
- }
-
-
- //------------------------------------------------------------------------------
- // MMSetIsObject
- //------------------------------------------------------------------------------
-
- void MMSetIsObject( void *block, char isObject )
- {
- BestFitHeap *heap = GetHeap(block,"MMSetIsObject");
- if( heap )
- heap->SetBlockIsObject(block,isObject);
- }
-
-
- //------------------------------------------------------------------------------
- // MMIsObject
- //------------------------------------------------------------------------------
-
- char MMIsObject( const void *block )
- {
- BestFitHeap *heap = GetHeap(block,"MMIsObject");
- if( heap )
- return heap->BlockIsObject(block);
- else
- return kMMFalse;
- }
-
-
- //------------------------------------------------------------------------------
- // MMMove
- //------------------------------------------------------------------------------
-
- void MMMove( void *dst, const void *src, size_t size )
- {
- if( size!=0 && src!=dst ) {
- #if MM_DEBUG
- static void *worldStart = LOWEST_POSSIBLE_ADDRESS();
- static void *worldEnd = HIGHEST_POSSIBLE_ADDRESS();
- const void *srcEnd = (char*)src+size;
- const void *dstEnd = (char*)dst+size;
- if( srcEnd<worldStart || src>worldEnd || dstEnd<worldStart || dst>worldEnd
- || (size&~0x0FFFFFFF) )
- MM_WARN("MMMove(%p,%p,%ld) looks weird", dst,src,size);
- if( gValidate>0 ) {
- MMValidateMemoryRange(src,srcEnd);
- MMValidateMemoryRange(dst,(char*)dst+size);
- }
- #endif
- PlatformCopyMemory((void*)src,dst,size);
- }
- }
-